Align PostgreSQL Recipe outputs with secret ownership - #298
Open
willdavsmith wants to merge 3 commits into
Open
Conversation
The Kubernetes recipe returned `secrets: { password, connectionString }`, but
the postgreSqlDatabases type declares no `secrets` property, so neither value
was reachable from an application. The Azure recipe in
recipe-packs/azure/aks-recipepack.bicep maps only `host`, and deliberately does
not use the `outputs.secrets` mechanism it uses one entry away for redisCaches.
That distinction is intentional. PostgreSQL administrator credentials flow into
the recipe as user-supplied properties, so there is nothing to hand back; Redis
access keys are generated by the infrastructure and must flow out. Drop the
unreachable secrets output so both platforms agree, and document the reasoning.
Also emit `port` as a string to match `type: string` on the resource type, and
update test/app.bicep to show the supported pattern: the application authors its
own Radius.Security/secrets resource and binds it into the container with
valueFrom.secretKeyRef. A connection cannot carry the password (sensitive
properties redact to null and are skipped by the containers recipe), so this is
the only way to deliver it, and it keeps the value out of the pod spec and off
the container resource, where env values are stored unencrypted.
Signed-off-by: Will Smith <willdavsmith@gmail.com>
Signed-off-by: willdavsmith <willdavsmith@gmail.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the Kubernetes postgreSqlDatabases recipe and its test application to align secret-handling behavior with the Azure implementation, ensuring credentials that flow into the recipe are not incorrectly emitted back as recipe secrets.
Changes:
- Removed the Kubernetes recipe
secretsoutput forpostgreSqlDatabasesand documented the rationale to prevent reintroducing it later. - Emitted
portas a string in the recipe output to match the resource type schema. - Updated the test app to demonstrate developer-authored
Radius.Security/secretsand binding the password into a consuming container viavalueFrom.secretKeyRef.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| Data/postgreSqlDatabases/recipes/kubernetes/bicep/kubernetes-postgresql.bicep | Removes unreachable secret outputs and aligns port output typing with the resource type schema. |
| Data/postgreSqlDatabases/test/app.bicep | Demonstrates the supported pattern of authoring a secrets resource and binding the password into a container by reference. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+196
to
+200
| // and should author its own Radius.Security/secrets resource, binding it with | ||
| // `valueFrom.secretKeyRef` (see test/app.bicep). This matches the Azure recipe in | ||
| // recipe-packs/azure/aks-recipepack.bicep, which maps only `host`. Contrast with | ||
| // redisCaches, where the access key is generated by the infrastructure and so is | ||
| // returned via `outputs.secrets`. |
The test application bound the password as POSTGRES_PASSWORD and named the
connection `postgres`, yielding CONNECTION_POSTGRES_* variables. The demo image
reads neither: samples/demo/src/db/repository.ts gates on
CONNECTION_POSTGRESQL_HOST and reads CONNECTION_POSTGRESQL_{PORT,USERNAME,
PASSWORD,DATABASE}. The container therefore never matched, silently fell back to
its in-memory store, and the test still passed because it only asserts that the
deployment succeeded.
Rename the connection to `postgresql` and bind the secret as
CONNECTION_POSTGRESQL_PASSWORD. That is the one variable Radius cannot supply
through the connection, because x-radius-sensitive properties redact to null on
reads and the containers recipe skips null values, so the binding fills the gap
rather than colliding with an injected variable.
Signed-off-by: Will Smith <willdavsmith@gmail.com>
Signed-off-by: willdavsmith <willdavsmith@gmail.com>
Signed-off-by: willdavsmith <willdavsmith@gmail.com>
willdavsmith
force-pushed
the
willdavsmith-postgresql-recipe-secret-pattern
branch
from
August 20, 2026 21:57
a56ad46 to
6ffec56
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Aligns the Kubernetes PostgreSQL Bicep and Terraform Recipes with the managed-secret ownership contract:
outputs.secrets.portvalue.Radius.Security/secretsresource for the consuming container and binds its password throughsecretKeyRef.postgresql, so the demo usesCONNECTION_POSTGRESQL_HOST,PORT,USERNAME,PASSWORD, andDATABASEand selects its PostgreSQL repository instead of silently falling back to the in-memory store.Secret ownership
Radius.Data/postgreSqlDatabasesreceivesusernameand the sensitivepasswordfrom the application. Those user-supplied inputs configure the Recipe-owned Kubernetes Secret used by the PostgreSQL pod, but they are not generated outputs and must not be returned as managed Recipe secrets. This matches the Azure PostgreSQL Recipe, which returns only infrastructure outputs.The preferred automatic input flow is to connect the container separately to the authored
Radius.Security/secretsresource, which PR #300 projects asCONNECTION_<NAME>_<KEY>variables. This PR deliberately keeps the explicitsecretKeyRefform because #300 is not merged and the shared PostgreSQL fixture is exercised independently by both Bicep and Terraform CI. The authored Radius Secret is namedpostgresql-client-credentials, distinct from the PostgreSQL Recipe'spostgresql-credentialsKubernetes Secret, so both validation modes can deploy without collision. Coordinated downstream verification can switch the fixture to the automatic Secret connection once #300 and the corresponding Radius producer-managed reference support are available together.Redis audit
No Redis files are changed. Redis accepts no credential input, so neither Kubernetes Recipe can echo a user-authored secret. Both Bicep and Terraform generate their connection URL from provisioned service outputs and emit the same
urlkey throughoutputs.secrets; Azure Redis similarly emits its infrastructure-generated authenticated connection string. The schema declaressecrets.nameandsecrets.url, and the test consumesurlby reference. This matches the ownership contract and is not analogous to PostgreSQL's input-password violation.Validation
terraform fmt -checkterraform init -backend=falseterraform validate(passes with existing Kubernetes provider deprecation warnings)git diff --checkLive Bicep and Terraform deployment validation is delegated to this PR's existing recipe CI because the local Recipe registry and Kubernetes cluster were unavailable.